package com.rtx.edi.platform.synctask.service;

import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.rtx.edi.model.api.bo.ApiMappingInfoBo;
import com.rtx.edi.model.api.po.PlApiMapping;
import com.rtx.edi.model.api.po.PlApiMappingStructure;
import com.rtx.edi.model.log.po.PlApiRequestContentLog;
import com.rtx.edi.model.log.po.PlApiRequestLog;
import com.rtx.edi.model.qm.RtxQMResponse;
import com.rtx.edi.platform.baseinfo.service.PlApiService;
import com.rtx.edi.platform.handler.JsonConvert;
import com.rtx.edi.platform.handler.TargetFieldHandle;
import com.rtx.edi.platform.handler.service.HandleSqlService;
import com.rtx.edi.platform.log.service.PlApiRequestContentLogService;
import com.rtx.edi.platform.synctask.api.GatWayAPI;
import com.rtx.edi.platform.synctask.handler.PlTaskHandler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;

@Service
public abstract class GatWayService implements GatWayAPI{
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private PlApiService plApiService;

	@Autowired
	PlApiRequestContentLogService plApiRequestContentLogService;
	
	@Autowired
	HandleSqlService handleSqlService;
	
	@Autowired
	PlTaskHandler plTaskHandler;
	
	ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 100, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100));


	/**
	 * 目标为api接口转发
	 * @return
	 */
	public String handel(String method,String body) {
		PlApiRequestLog log =new PlApiRequestLog();
		PlApiRequestContentLog content = new PlApiRequestContentLog();
		String result = null;
		
		try {
			//获取method
			log.setRequestData1(body);
			content.setRequestContent(body);
			log.setRequestData2(method);
			
			
			logger.info("请求数据：{}",body);
			//转化为JSON
			JSONObject sourceJson = plTaskHandler.getJSONObject(body);
			logger.info("转化为JSON结果：{}",sourceJson.toString());
			
			PlApiMapping plApiMapping = plApiService.getPlApiMappingByApiMappingCode(method);
			Assert.notNull(plApiMapping,"对接场景编号：" + method + "不存在");
			//获取场景映射信息
			ApiMappingInfoBo apiInfo = plApiService.getApiMappingInfo(plApiMapping.getCompanyId(),plApiMapping.getId(),log);
			//获取报文结构
			List<PlApiMappingStructure> structureList = plApiService.getPlApiMappingStructure(apiInfo.getApiMappingId());
			//转化报文结构
			JsonConvert convert = new JsonConvert(sourceJson.toString(),apiInfo.getTargetJsonTemplate(),structureList,null);
			convert.convert();
			
			String targetjson = convert.getTargetJosn();
			
			log.setRequestData3(targetjson);
			
			String logkeyPath = Optional.ofNullable(apiInfo.getLogkey()).orElse("");
			for(String temppath:logkeyPath.split(",")) {
				String path = StrUtil.replaceLast(temppath,"数组","[]");
				if(StringUtils.hasLength(path)){
					String logkey = String.valueOf(sourceJson.getByPath(path));
					if(StringUtils.hasLength(log.getLogkey())) {
						log.setLogkey(log.getLogkey()+"-"+logkey);
					}else {
						log.setLogkey(logkey);
					}
					
				}
			}

			
			//处理字段 配置得转换脚本
			targetjson = TargetFieldHandle.handleFieldScript(targetjson, structureList);
			
			//处理字段 设置默认值
			targetjson = TargetFieldHandle.handleTargetDefaultValue(targetjson, structureList);
			
			logger.info("转化为目标JSON：{}",targetjson);
			
			
			
			//日志
			apiInfo.setLog(log);
			apiInfo.setContent(content);

			//不同实现类实现不同接口
			result = handleTarget(targetjson,apiInfo);
			
			if(!StringUtils.hasLength(result)) {
				content.setResponseContent(result);
			}
			
		} catch (Exception e) {
			logger.error("请求异常-",e);
			RtxQMResponse res = new RtxQMResponse();
			res.setFailure(e.getMessage());
			result = com.alibaba.fastjson.JSON.toJSONString(res);
		}
		
		//记录日志
		plApiRequestContentLogService.inserRtxLog("ris_edi", content, log);
		return result;
	};
	
	void handleSkipMapping(){
		
	}
	
	abstract protected String handleTarget(String targetjson,ApiMappingInfoBo bo)throws Exception;
	
	
	
	/**
	 * 目标为api接口转发
	 * @param request
	 * @return
	 * @throws IOException 
	 */
	public String handel(HttpServletRequest request) throws IOException{
		String method = request.getParameter("method");
		String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
		return handel(method,body);
	};
	
	/**
	 * 目标为api接口转发
	 * @param request
	 * @return
	 * @throws IOException 
	 */
	public String asynchronousHandel(HttpServletRequest request) throws IOException{
		String method = request.getParameter("method");
		String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
		
		try {
			//异步下发到wms
			pool.execute(()->{
				List<String> list = JSON.parseArray(body, String.class);
				for(String eachBody:list) {
					handel(method,eachBody);
				}
	        });
		} catch (Exception e) {
			logger.error("对接场景异步下发wms异常-",e);
		}

		
		RtxQMResponse res = new RtxQMResponse();
		res.setSuccess("success");
		return JSON.toJSONString(res);
	};
	
}
